package com.zero2oneit.mall.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.zero2oneit.mall.common.bean.member.*;
import com.zero2oneit.mall.common.utils.DateUtil;
import com.zero2oneit.mall.common.utils.R;
import com.zero2oneit.mall.common.utils.StringUtils;
import com.zero2oneit.mall.member.mapper.*;
import com.zero2oneit.mall.member.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class MemberAccountsServiceImpl extends ServiceImpl<MemberAccountsMapper, MemberAccounts> implements MemberAccountsService {

    @Autowired
    private MemberAccountsMapper memberAccountsMapper;
    @Autowired
    private MemberLeadersMapper memberLeadersMapper;
//    @Autowired
//    private LoggingService loggingService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private DistributeLogMapper distributeLogMapper;
    @Autowired
    private MemberInfoMapper memberInfoMapper;
    @Autowired
    private MembershipDistributionService membershipDistribute;
    @Autowired
    private MemberShareRecordMapper memberShareRecordMapper;
    @Autowired
    private MemberStarInfoService memberStarInfoService;
    @Autowired
    private MemberStarLevelService memberStarLevelService;
    @Autowired
    private  MemberStarLevelMapper memberStarLevelMapper;
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    @Override
    @Transactional
    public void updateAccountsById(MemberAccounts oldAccounts, MemberAccounts newAccounts, int type, String remark) throws Exception {
//            loggingService.insertLog(oldAccounts, newAccounts, type, remark);
            memberAccountsMapper.updateAccountsById(oldAccounts);
    }
    @Transactional
    @Override
    public int commissionEdit(BigDecimal commission, String memberId) {
        return memberAccountsMapper.commissionEdit(commission,memberId);
    }
    @Transactional
    @Override
    public void shareMoneyEdit(BigDecimal shareMoney, String memberId) {
        memberAccountsMapper.shareMoneyEdit(shareMoney, memberId);
    }
    @Transactional
    @Override
    public String shareMoneyQuery(String memberId) {
        return memberAccountsMapper.shareMoneyQuery(memberId);
    }

    @Override
    public BigDecimal shareCommissions(String userId) {
        return  memberAccountsMapper.shareCommissions(userId);
    }

    @Override
    public void sharingCommissionEdit(BigDecimal withdrawalPrice, String memberId) {
        memberAccountsMapper.sharingCommissionEdit(withdrawalPrice,memberId);
    }
    @Override
    public String queryOld(String memberId) {
        return memberAccountsMapper.queryOld(memberId);
    }

    @Override
    public R withdrawComm(String tyep, BigDecimal amount) {
        Map<String, String> weekDate = DateUtil.getWeekDate();
        String sundayDate=weekDate.get("sundayDate");
        String mondayDate=weekDate.get("mondayDate");
        return R.ok();
    }

    @Transactional
    public void starMemManageDistru(String memberId, BigDecimal orderMoney, String orderId) {
        BigDecimal hundred = new BigDecimal("100");
        MemberInfo memberInfo=getMemberInfoById(memberId);
        memberStarInfoService.addConsume(memberId,orderMoney);
        MemberStarLevel memberStarLevel;
        if (memberInfo.getStarOpen() == 1 && memberInfo.getStarId() != 0) {
            //计算全网分红金
            QueryWrapper<MemberStarLevel> wrapper = new QueryWrapper<>();
            wrapper.orderByAsc("id");
            List<MemberStarLevel> memberStarLevels = memberStarLevelMapper.selectList(wrapper);
            BigDecimal two = memberStarLevels.get(1).getAllDividends().multiply(orderMoney);
            BigDecimal three = memberStarLevels.get(2).getAllDividends().multiply(orderMoney);
            BigDecimal four = memberStarLevels.get(3).getAllDividends().multiply(orderMoney);
            memberStarLevelService.addManageAccount(two,three,four);
            QueryWrapper<MemberShareRecord> wp = new QueryWrapper<>();
            wp.eq("order_id",orderId).eq("level",2);
            MemberShareRecord memberShareRecord = memberShareRecordMapper.selectOne(wp);
            if(memberShareRecord != null && (memberShareRecord.getRefundCount() != memberShareRecord.getCount())){
                Map<String,BigDecimal> map= memberShareRecordMapper.selectShareMoney(orderId);
                MemberInfo memberInfoStar =getSuperiorStarTwo(memberShareRecord.getMemberId());
                if(memberInfoStar!=null){
                    memberStarLevel = memberStarLevels.get(memberInfoStar.getStarId() - 1);
                    addShareMoney(memberInfoStar.getMemberId(),map.get("oneShare").multiply(memberStarLevel.getTwoManage()).divide(hundred,2,BigDecimal.ROUND_DOWN),"团队培育奖");
                    addShareMoney(memberInfoStar.getMemberId(),map.get("twoShare").multiply(memberStarLevel.getOneManage()).divide(hundred,2,BigDecimal.ROUND_DOWN),"团队培育奖");
                }
            }
        }
    }
    @Transactional
    public void addShareMoney(String memberId, BigDecimal oneShare, String mark) {
        MemberAccounts memberAccount = getMemberAccountsById(memberId);
        if (memberAccount.getShareMoney() == null) memberAccount.setShareMoney(new BigDecimal("0"));
        memberAccount.setShareMoney(memberAccount.getShareMoney().add(oneShare));
        redisTemplate.opsForHash().put("member:accounts:info", memberId, JSON.toJSONString(memberAccount));
        Map<String, String> mapLog = new HashMap<>();
        mapLog.put("memberId", memberId);
        mapLog.put("shareMoney", String.valueOf(oneShare));
        mapLog.put("type", "10");
        mapLog.put("remark", mark);
        shareMoney(mapLog);
    }

    @Transactional
    public void hnPlatformDistribute(BigDecimal platformJf, BigDecimal businessJf, BigDecimal businessMoney, String businessId) {
        Map<String,BigDecimal> map= distributeLogMapper.GetAllBalance(9,8,businessId);
        insertDistributeLog(platformJf,3,map.get("totalPlatformJf").add(platformJf),"二级分销候鸟平台积分","+",businessId);
        insertDistributeLog(businessJf,9,map.get("totalBusinessJf").add(businessJf),"二级分销候鸟商家积分","+",businessId);
        insertDistributeLog(businessMoney,8,map.get("totalBusinessMoney").add(businessMoney),"二级分销候鸟商家金额","+",businessId);
    }

    @Transactional
    public void ygPlatformDistribute(BigDecimal platformJf, BigDecimal businessJf, BigDecimal businessMoney, String businessId) {
        Map<String,BigDecimal> map= distributeLogMapper.GetAllBalance(7,6,businessId);
        insertDistributeLog(platformJf,3,map.get("totalPlatformJf").add(platformJf),"二级分销商场平台积分","+","888");
        insertDistributeLog(businessJf,7,map.get("totalBusinessJf").add(businessJf),"二级分销商场商家积分","+",businessId);
        insertDistributeLog(businessMoney,6,map.get("totalBusinessMoney").add(businessMoney),"二级分销商场商家金额","+",businessId);
        //给商家账号加钱加积分
    }
    @Transactional
    public void yzPlatformDistribute(BigDecimal platformJf, BigDecimal businessJf, BigDecimal businessMoney, String businessId) {
        Map<String,BigDecimal> map= distributeLogMapper.GetAllBalance(2,1,businessId);
        insertDistributeLog(platformJf,3,map.get("totalPlatformJf").add(platformJf),"二级分销驿站平台积分","+",businessId);
        insertDistributeLog(businessJf,2,map.get("totalBusinessJf").add(businessJf),"二级分销驿站商家积分","+",businessId);
        insertDistributeLog(businessMoney,1,map.get("totalBusinessMoney").add(businessMoney),"二级分销驿站商家金额","+",businessId);
    }


    @Transactional
    public void insertDistributeLog(BigDecimal price, Integer typeState, BigDecimal total, String remark, String sign, String businessId){
        DistributeLog platformJfLog = new DistributeLog();
        platformJfLog.setPrice(price);
        platformJfLog.setTypeState(typeState);
        platformJfLog.setBalance(total);
        platformJfLog.setCreateTime(new Date());
        platformJfLog.setRemark(remark);
        platformJfLog.setSign(sign);
        platformJfLog.setBusinessId(businessId);
        distributeLogMapper.insert(platformJfLog);
    }
    @Override
    public BigDecimal commissionInquire(String userId) {
        return memberAccountsMapper.commissionInquire(userId);
    }
    @Transactional
    public void upDistribution(MemberAccounts memberAccount,BigDecimal exp,String remark) {
        MemberAccounts oldAccounts = new MemberAccounts();
        oldAccounts.setMemberPoints(exp);
        memberAccount.setMemberPoints(memberAccount.getMemberPoints().add(exp));
        oldAccounts.setMemberId(memberAccount.getMemberId());
        try {
            updateAccountsById(oldAccounts,memberAccount,9,remark);
        } catch (Exception e) {
            throw new RuntimeException();
        }
        redisTemplate.opsForHash().put("member:accounts:info", memberAccount.getMemberId(), JSON.toJSONString(memberAccount));
    }
    /*全网分红金找上级*/
    @Transactional
    public MemberInfo getSuperiorStarTwo(String memberId) {
        List<LeaderVo> allLeader = getAllLeader(memberId);
        MemberInfo memberInfo=null;
        for (LeaderVo leaderVo : allLeader) {
            if(leaderVo.getStarId()>=2 && leaderVo.getStarOpen()==1){
                memberInfo= getMemberInfoById(leaderVo.getMemberId());
                break;
            }
        }
        return memberInfo;
    }

    @Transactional
    @Override
    public R yzShareCommissionConfirm(List<Map<String, String>> list) {
        MembershipDistribution distribution = membershipDistribute.yzScDistribution(7);
        for (Map<String, String> map : list) {
            String goodId = map.get("goodId");
            QueryWrapper<MemberShareRecord> select = new QueryWrapper<>();
            select.eq("level", 1).eq("good_id", goodId).eq("platform","驿站");
            MemberShareRecord record = memberShareRecordMapper.selectOne(select);
            if (record != null && (record.getRefundCount()!=record.getCount())) {
                BigDecimal allMoney = record.getShare().multiply(BigDecimal.valueOf(record.getCount()-record.getRefundCount()));
                MemberAccounts memberAccount = getMemberAccountsById(record.getMemberId());
                if (memberAccount.getShareMoney() == null) memberAccount.setShareMoney(new BigDecimal("0"));
                memberAccount.setShareMoney(memberAccount.getShareMoney().add(allMoney));
                redisTemplate.opsForHash().put("member:accounts:info", record.getMemberId(), JSON.toJSONString(memberAccount));
                Map<String, String> mapLog = new HashMap<>();
                mapLog.put("memberId", record.getMemberId());
                mapLog.put("shareMoney", String.valueOf(allMoney));
                mapLog.put("type", "10");
                mapLog.put("remark", "驿站确认收货上级分享佣金");
                shareMoney(mapLog);
                record.setStatus(1);
                memberShareRecordMapper.updateById(record);
                QueryWrapper<MemberShareRecord> select2 = new QueryWrapper<>();
                select2.eq("level", 2).eq("good_id", goodId).eq("platform","驿站");
                MemberShareRecord recordTwo = memberShareRecordMapper.selectOne(select2);
                if(recordTwo!=null && (recordTwo.getRefundCount() != recordTwo.getCount())){
                    if ("1".equals(distribution.getOpen())) shareLeader(recordTwo, "驿站确认收货上上级分享佣金");
                }
            }
        }
        return R.ok();
    }



    @Override
    @Transactional
    public R ygShareCommissionConfirm(List<Map<String, String>> list) {
        MembershipDistribution distribution = membershipDistribute.yzScDistribution(8);
        for (Map<String, String> map : list) {
            String goodId = map.get("goodId");
            QueryWrapper<MemberShareRecord> select = new QueryWrapper<>();
            select.eq("level", 1).eq("good_id", goodId).eq("platform","全国包邮");
            MemberShareRecord record = memberShareRecordMapper.selectOne(select);
            if (record != null && (record.getCount()!=record.getRefundCount())) {
                BigDecimal allMoney = record.getShare().multiply(BigDecimal.valueOf(record.getCount()-record.getRefundCount()));
                MemberAccounts memberAccount = getMemberAccountsById(record.getMemberId());
                if (memberAccount.getShareMoney() == null) memberAccount.setShareMoney(new BigDecimal("0"));
                memberAccount.setShareMoney(memberAccount.getShareMoney().add(allMoney));
                redisTemplate.opsForHash().put("member:accounts:info", record.getMemberId(), JSON.toJSONString(memberAccount));
                Map<String, String> mapLog = new HashMap<>();
                mapLog.put("memberId", record.getMemberId());
                mapLog.put("shareMoney", String.valueOf(allMoney));
                mapLog.put("type", "10");
                mapLog.put("remark", "全国包邮确认收货上级分享佣金");
                shareMoney(mapLog);
                record.setStatus(1);
                memberShareRecordMapper.updateById(record);
                QueryWrapper<MemberShareRecord> select2 = new QueryWrapper<>();
                select2.eq("level", 2).eq("good_id", goodId).eq("platform","全国包邮");
                MemberShareRecord recordTwo = memberShareRecordMapper.selectOne(select2);
                if(recordTwo!=null && (recordTwo.getRefundCount() != recordTwo.getCount())){
                    if ("1".equals(distribution.getOpen())) shareLeader(recordTwo,"全国包邮确认收货上上级分享佣金");
                }
            }
        }
        return R.ok();
    }
    @Transactional
    public void shareLeader(MemberShareRecord record, String mark) {
        MemberAccounts memberAccount = getMemberAccountsById(record.getMemberId());
        BigDecimal allMoney = record.getShare().multiply(BigDecimal.valueOf(record.getCount()-record.getRefundCount()));
        if (memberAccount.getShareMoney() == null) memberAccount.setShareMoney(new BigDecimal("0"));
        memberAccount.setShareMoney(memberAccount.getShareMoney().add(allMoney));
        redisTemplate.opsForHash().put("member:accounts:info", memberAccount.getMemberId(), JSON.toJSONString(memberAccount));
        Map<String, String> mapLog = new HashMap<>();
        mapLog.put("memberId", memberAccount.getMemberId());
        mapLog.put("shareMoney", String.valueOf(allMoney));
        mapLog.put("type", "10");
        mapLog.put("remark", mark);
        shareMoney(mapLog);
        record.setStatus(1);
        memberShareRecordMapper.updateById(record);
    }

    /**
     * 站长分享佣金 - 记录添加
     * @param map
     * @return
     */
    @Transactional
    public void shareMoney(Map<String,String> map){
        String memberId = map.get("memberId");
        BigDecimal shareMoney = new BigDecimal(map.get("shareMoney"));
        String type = map.get("type");
        String remark = map.get("remark");
        shareMoneyEdit(shareMoney, memberId);
        String totalCommission= shareMoneyQuery(memberId);
        if(shareMoney != null && !"".equals(shareMoney) && ! "0".equals(shareMoney.toString())){
            String sign= shareMoney.compareTo(BigDecimal.ZERO)> 0 ? "+" :"-";
//            loggingService.insertShareMoney(memberId,shareMoney,totalCommission,type,remark,sign);
        }
    }

    public MemberInfo getMemberInfoById(String memberId){
        MemberInfo memberInfo;
        String s = redisTemplate.opsForValue().get("member:info:" + memberId);
        if (StringUtils.isEmpty(s)) {
            memberInfo = memberInfoMapper.selectById(memberId);
            redisTemplate.opsForValue().set("member:info:" + memberId, JSONArray.toJSONString(memberInfo));
        } else {
            memberInfo = JSONObject.parseObject(s, MemberInfo.class);
        }
        return memberInfo;
    }

    public MemberAccounts getMemberAccountsById(String memberId){
        String accounts = (String) redisTemplate.opsForHash().get("member:accounts:info", memberId);
        if (StringUtils.isEmpty(accounts)) {
            MemberAccounts memberAccounts = memberAccountsMapper.selectById(memberId);
            redisTemplate.opsForHash().put("member:accounts:info", memberId, JSON.toJSONString(memberAccounts));
            accounts = (String) redisTemplate.opsForHash().get("member:accounts:info", memberId);
        }
        return JSON.parseObject(accounts, MemberAccounts.class);
    }
    @Override
    public void yzShareCommissionRefund(Map map) {
        QueryWrapper<MemberShareRecord> select = new QueryWrapper<>();
        select.eq("order_id", map.get("orderId")).eq("good_id", map.get("goodId")).eq("platform",map.get("platform"));
        List<MemberShareRecord> record = memberShareRecordMapper.selectList(select);
        for (MemberShareRecord memberShareRecord : record) {
            Integer count= Integer.valueOf(String.valueOf(map.get("refundCount")));
            if (memberShareRecord != null) {
                memberShareRecord.setRefundCount(memberShareRecord.getRefundCount()+count);
                memberShareRecordMapper.updateById(memberShareRecord);
            }
        }
    }

    public List<LeaderVo> getAllLeader(String memberId) {
      return memberLeadersMapper.getAllLeader(memberId);
    }

}
